package com.meida.module.arc.provider.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.meida.common.base.entity.EntityMap;
import com.meida.common.base.utils.FlymeUtils;
import com.meida.common.mybatis.base.service.impl.BaseServiceImpl;
import com.meida.common.mybatis.model.ResultBody;
import com.meida.common.mybatis.query.CriteriaDelete;
import com.meida.common.mybatis.query.CriteriaQuery;
import com.meida.common.mybatis.query.CriteriaSave;
import com.meida.common.mybatis.query.CriteriaUpdate;
import com.meida.common.utils.ApiAssert;
import com.meida.module.arc.client.entity.*;
import com.meida.module.arc.client.enums.ArchiveEnumInteger;
import com.meida.module.arc.client.utils.ArcUtils;
import com.meida.module.arc.provider.mapper.ArcFieldMapper;
import com.meida.module.arc.provider.service.ArcCategorySecondService;
import com.meida.module.arc.provider.service.ArcFieldService;
import com.meida.module.arc.provider.service.ArcFieldSysService;
import com.meida.module.arc.provider.service.ArcSecondFieldService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 字段配置表接口实现类
 *
 * @author flyme
 * @date 2021-11-22
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class ArcFieldServiceImpl extends BaseServiceImpl<ArcFieldMapper, ArcField> implements ArcFieldService {

    @Autowired
    private ArcFieldSysService arcFieldSysService;

    @Autowired
    @Lazy
    private ArcCategorySecondService arcCategorySecondService;

    @Autowired
    @Lazy
    private ArcSecondFieldService arcSecondFieldService;

    private boolean checkEnName(String enName, Long categoryId, Long exclusionId) {
       /* CriteriaQuery<ArcFieldSys> query = new CriteriaQuery<ArcFieldSys>(ArcFieldSys.class);
        query.lambda().eq(ArcFieldSys::getEnName, enName);
        if (FlymeUtils.isNotEmpty(exclusionId)) {
            query.lambda().ne(ArcFieldSys::getFieldSysId, exclusionId);
        }
        Long count = arcFieldSysService.getBaseMapper().selectCount(query);
        if (count > 0) {
            return false;
        }
*/
        CriteriaQuery<ArcField> fdQuery = new CriteriaQuery<ArcField>(ArcField.class);
        fdQuery.lambda().eq(ArcField::getFieldName, enName)
                .eq(ArcField::getCategoryId, categoryId);
        if (FlymeUtils.isNotEmpty(exclusionId)) {
            fdQuery.lambda().ne(ArcField::getFieldId, exclusionId);
        }
        Long fdCount = this.baseMapper.selectCount(fdQuery);
        if (fdCount > 0) {
            return false;
        }

        Field[] declaredFields = ArcInfo.class.getDeclaredFields();
        List<String> fieldsName = Arrays.stream(declaredFields).map(item -> {
            return item.getName();
        }).collect(Collectors.toList());

        if (FlymeUtils.isNotEmpty(exclusionId) && fieldsName.contains(enName)) {
            return false;
        }

        return true;
    }

    private boolean checkCnName(String cnName, Long categoryId, Long exclusionId) {

        CriteriaQuery<ArcField> fdQuery = new CriteriaQuery<ArcField>(ArcField.class);
        fdQuery.lambda().eq(ArcField::getFieldCnName, cnName)
                .eq(ArcField::getCategoryId, categoryId);
        if (FlymeUtils.isNotEmpty(exclusionId)) {
            fdQuery.lambda().ne(ArcField::getFieldId, exclusionId);
        }
        Long fdCount = this.baseMapper.selectCount(fdQuery);
        if (fdCount > 0) {
            return false;
        }
        return true;
    }

    @Override
    public ResultBody beforeAdd(CriteriaSave cs, ArcField field, EntityMap extra) {
        ApiAssert.isNotEmpty("门类id不能为空", field.getCategoryId());
        ApiAssert.isNotEmpty("字段英文名称不能为空", field.getFieldName());
        ApiAssert.isNotEmpty("字段数据类型不能为空", field.getDataType());
        String enKey = "enName:" + field.getCategoryId() + ":" + field.getFieldName();
        String fieldName = "fieldName:" + field.getCategoryId() + ":" + field.getFieldName();

        Object o1 = redisUtils.get(enKey);
        Object o2 = redisUtils.get(fieldName);
        if (ObjectUtil.isNotNull(o1) || ObjectUtil.isNotNull(o2)) {
            return ResultBody.failed("英文名称不能重复");
        }
        //校验字段名称是否为空
        if (!checkEnName(field.getFieldName(), field.getCategoryId(), null)) {
            ApiAssert.failure("字段英文名称不能重复");
        }
        //校验中文字段名称是否为空
        if (!checkCnName(field.getFieldCnName(), field.getCategoryId(), null)) {
            ApiAssert.failure("中文名称已重复，请更换！");
        }
        if (!ArcUtils.isValidString(field.getFieldName())) {
            ApiAssert.failure("字段英文名称只能包含数字 字母 下划线");
        }
        redisUtils.set("fieldName:" + field.getCategoryId() + ":" + field.getFieldName(), field.getFieldName());

        field.setIsBlob(ArchiveEnumInteger.IS_TRUE.getCode());
        field.setIsSystem(ArchiveEnumInteger.IS_NOT_SYSTEM.getCode());
        field.setDeleted(0);
        //数字类型  必须为数字框
        field.setInType(field.getDataType().intValue() == 2 ? 2 : 1);
        field.setInSeq(0);
        field.setInLength(250);
        field.setInMaxLength(FlymeUtils.isNotEmpty(field.getColumnLength()) ? field.getColumnLength() : 250);
        field.setInMinLength(0);
        field.setInLine(0);
        field.setInShow(0);
        field.setInRequire(0);
        field.setInSearch(0);
        field.setInAutoGen(0);
        field.setInAutoPlus(0);
        field.setInInherit(0);
        field.setInAutoZero(0);
        field.setInZeroNum(0);
        field.setInNoRepeat(0);
        field.setOutSeq(0);
        field.setOutLength(250);
        field.setOutFormat(2);
        field.setOutIsShow(0);
        field.setOutIsOrder(0);
        field.setOutOrderSeq(0);
        field.setOutOrderType("ASC");
        field.setIsArcNum(0);
        field.setArcSeq(0);
        field.setSeq(99999);
        return ResultBody.ok();
    }

    @Override
    public ResultBody beforeEdit(CriteriaUpdate<ArcField> cu, ArcField field, EntityMap extra) {
        ApiAssert.isNotEmpty("字段id不能为空", field.getFieldId());
        ArcField obj = this.getById(field.getFieldId());
        Pattern p = Pattern.compile("/[\\/:*?\"<>|]/g");
        if (FlymeUtils.isNotEmpty(field.getArcConnect()) && (p.matcher(field.getArcConnect()).find() || field.getArcConnect().contains("\\"))) {
            return ResultBody.failed("连接符不能包含\\/:*?\"<>|");
        }

        if (FlymeUtils.isNotEmpty(field.getFieldName()) && !field.getFieldName().equals(obj.getFieldName())) {
            return ResultBody.failed("字段英文名称不能修改");
        }
        if (FlymeUtils.isNotEmpty(field.getDataType()) && !field.getDataType().equals(obj.getDataType())) {
            return ResultBody.failed("字段数据类型不能修改");
        }
        //校验中文字段名称是否为空
        /*if (!checkCnName(field.getFieldCnName(), field.getCategoryId(), field.getFieldId())) {
            return ResultBody.failed("中文名称已重复，请更换！");
        }*/
        if (FlymeUtils.isNotEmpty(field.getIsMount())) {
            //因为一个门类只有一个挂接字段，所以要重置该门类所有isMount为false
            UpdateWrapper<ArcField> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda().eq(ArcField::getCategoryId, obj.getCategoryId())
                    .set(ArcField::getIsMount, ArchiveEnumInteger.IS_FALSE.getCode());
            this.update(updateWrapper);
            if ("arcNo".equals(obj.getFieldName())) {
                field.setIsMount(ArchiveEnumInteger.IS_FALSE.getCode());
                cu.getRequestMap().put("arcNo", ArchiveEnumInteger.IS_FALSE.getCode());
            }
        }

//        if(FlymeUtils.isNotEmpty(field.getInLength())){
//            field.setOutLength(field.getInLength());
//        }
        return ResultBody.ok();
    }

    @Override
    public ResultBody beforeDelete(CriteriaDelete<ArcField> cd) {
        ApiAssert.isNotEmpty("字段id不能为空", cd.getIdValue());
        ArcField obj = this.getById(cd.getIdValue());
        if (ArchiveEnumInteger.IS_SYSTEM.getCode().equals(obj.getIsSystem())) {
            return ResultBody.failed("不能删除系统字段");
        }
        String enKey = "enName:" + obj.getFieldName();
        String fieldName = "fieldName:" + obj.getCategoryId() + ":" + obj.getFieldName();

        Object o1 = redisUtils.get(enKey);
        Object o2 = redisUtils.get(fieldName);
        if (ObjectUtil.isNotNull(o2)) {
            redisUtils.del(fieldName);
        }
        if (ObjectUtil.isNotNull(o1)) {
            redisUtils.del(enKey);
        }
        return ResultBody.ok();
    }

    @Override
    public ResultBody beforeListEntityMap(CriteriaQuery<ArcField> cq, ArcField t, EntityMap requestMap) {
        ApiAssert.isNotEmpty("门类id不能为空", t.getCategoryId());
        cq.lambda().eq(ArcField::getCategoryId, t.getCategoryId());
        cq.orderByAsc("seq");
        return ResultBody.ok();
    }


    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public ResultBody beforePageList(CriteriaQuery<ArcField> cq, ArcField fd, EntityMap requestMap) {
        cq.orderByDesc("field.createTime");
        return ResultBody.ok();
    }

    @Override
    public void batchAddArcField(Long categoryId) {
        ApiAssert.isNotEmpty("创建门类字段，门类id不能为空", categoryId);
        Field[] declaredFields = ArcInfo.class.getDeclaredFields();
        List<String> fieldsName = Arrays.stream(declaredFields).map(item -> {
            return item.getName();
        }).collect(Collectors.toList());
        List<ArcFieldSys> fieldList = arcFieldSysService.list();
        //字段表默认只添加业务字段，不添加系统字段
        //判断业务字段是在档案默认字段范围内 isBlob为0 否则为1
        List<ArcField> fields = new ArrayList<>();
        for (int i = 0; i < fieldList.size(); i++) {
            ArcFieldSys item = fieldList.get(i);
            if (ArchiveEnumInteger.IS_BIZ_FIELD.getCode().equals(item.getType())) {
                ArcField field = new ArcField();
                if (fieldsName.contains(item.getEnName())) {
                    field.setIsBlob(ArchiveEnumInteger.IS_FALSE.getCode());
                } else {
                    field.setIsBlob(ArchiveEnumInteger.IS_TRUE.getCode());
                }
                field.setFieldId(IdWorker.getId());
                field.setDeleted(0);
                field.setCategoryId(categoryId);
                field.setFieldName(item.getEnName());
                field.setFieldCnName(item.getCnName());
                field.setDataType(item.getDataType());
                field.setDefaultValue(item.getDefaultValue());
                field.setColumnLength(item.getLength());
                field.setInType(item.getDataType().intValue() == 2 ? 2 : 1);
                field.setInSeq(i);
                field.setInLength(250);
                field.setInMaxLength(250);
                field.setInMinLength(0);
                field.setInLine(0);
                field.setInShow(0);
                field.setInRequire(0);
                field.setInSearch(0);
                field.setInAutoGen(0);
                field.setInAutoPlus(0);
                field.setInInherit(0);
                field.setInAutoZero(0);
                field.setInZeroNum(0);
                field.setInNoRepeat(0);
                field.setOutSeq(i);
                field.setOutLength(250);
                field.setOutFormat(2);
                field.setOutIsShow(0);
                field.setOutIsOrder(0);
                field.setOutOrderSeq(0);
                field.setOutOrderType("ASC");
                field.setIsArcNum(0);
                field.setArcSeq(0);
                field.setSeq(i);
                field.setIsSystem(ArchiveEnumInteger.IS_SYSTEM.getCode());
                fields.add(field);
            }
        }
        if (fields.size() > 0) {
            //this.saveBatch(fields);
            this.mutiInsert(fields);
        }
    }

    @Override
    public ResultBody upOrDown(Map var1) {
        ApiAssert.isNotEmpty("字段id不能为空", var1.get("fieldId"));
        ApiAssert.isNotEmpty("移动类型不能为空", var1.get("type"));
        ApiAssert.isNotEmpty("业务类型不能为空", var1.get("bizType"));
        //排序为从小到大排   type为1为上移  2为下移 3拖动
        Integer type = NumberUtil.parseInt(var1.get("type").toString());
        Integer bizType = NumberUtil.parseInt(var1.get("bizType").toString());
        if (type != 1 && type != 2 && type != 3 && type != 4) {
            ApiAssert.failure("移动类型只能为上移或下移");
        }

        if (4 == type) {
            List<ArcField> upList = new ArrayList<>();
            List<String> split = StrUtil.split(var1.get("fieldId").toString(), ',');
            for (int i = 0; i < split.size(); i++) {
                ArcField toArcField = new ArcField();
                toArcField.setFieldId(NumberUtil.parseLong(split.get(i)));
                switch (bizType) {
                    case 1://著录排序（门类表所有字段都为默认著录字段  不做过滤）
                        toArcField.setInSeq(i);
                        break;
                    case 2://档号排序 （过滤是档号的数据）
                        toArcField.setArcSeq(i);
                        break;
                    case 3://浏览排序设置排序 （过滤是排序字段的数据）
                        toArcField.setOutOrderSeq(i);
                        break;
                    case 4://4浏览界面排序 （过滤是浏览界面的数据）
                        toArcField.setOutSeq(i);
                        break;
                    default:
                        break;
                }
                upList.add(toArcField);
            }
            return ResultBody.ok(this.saveOrUpdateBatch(upList));
        }
        Object fromIndex = var1.get("fromIndex");
        Object toIndex = var1.get("toIndex");
        if (type == 3) {
            ApiAssert.isNotEmpty("拖动角标来源不能为空", var1.get("fromIndex"));
            ApiAssert.isNotEmpty("拖动角标目标不能为空", var1.get("toIndex"));
        }
        Long fieldId = NumberUtil.parseLong(var1.get("fieldId").toString());
        ArcField fd = this.getById(fieldId);
        CriteriaQuery<ArcField> query = new CriteriaQuery<ArcField>(ArcField.class);
        query.lambda().eq(ArcField::getCategoryId, fd.getCategoryId());//所有对应业务类型的列表
        //业务类型（1，著录排序，2档号排序，3浏览排序设置排序，4浏览界面排序）
        switch (bizType) {
            case 1://著录排序（门类表所有字段都为默认著录字段  不做过滤）
                query.lambda().eq(ArcField::getInShow, ArchiveEnumInteger.IS_TRUE.getCode());
                query.orderByAsc("inSeq");
                break;
            case 2://档号排序 （过滤是档号的数据）
                query.lambda().eq(ArcField::getIsArcNum, ArchiveEnumInteger.IS_TRUE.getCode());
                query.orderByAsc("arcSeq");
                break;
            case 3://浏览排序设置排序 （过滤是排序字段的数据）
                query.lambda().eq(ArcField::getOutIsOrder, ArchiveEnumInteger.IS_TRUE.getCode());
                query.orderByAsc("outOrderSeq");
                break;
            case 4://4浏览界面排序 （过滤是浏览界面的数据）
                query.lambda().eq(ArcField::getOutIsShow, ArchiveEnumInteger.IS_TRUE.getCode());
                query.orderByAsc("outSeq");
                break;
            default:
                ApiAssert.failure("业务类型错误");
                break;
        }
        List<ArcField> list = this.list(query);
        if (type == 3) {//单独处理拖动问题
            int fromIndexInt = Integer.parseInt(fromIndex.toString());
            int toIndexInt = Integer.parseInt(toIndex.toString());
            if (fromIndexInt == toIndexInt) {
                ApiAssert.failure("移动前后角标不能相等");
            }
            if (fromIndexInt >= list.size() || fromIndexInt < 0 || toIndexInt >= list.size() || toIndexInt < 0) {
                ApiAssert.failure("移动前后角标不能越界");
            }
            List<ArcField> updateObj = new ArrayList<>();
            ArcField toArcField = new ArcField();
            toArcField.setFieldId(fieldId);
            switch (bizType) {
                case 1://著录排序（门类表所有字段都为默认著录字段  不做过滤）
                    toArcField.setInSeq(toIndexInt);
                    break;
                case 2://档号排序 （过滤是档号的数据）
                    toArcField.setArcSeq(toIndexInt);
                    break;
                case 3://浏览排序设置排序 （过滤是排序字段的数据）
                    toArcField.setOutOrderSeq(toIndexInt);
                    break;
                case 4://4浏览界面排序 （过滤是浏览界面的数据）
                    toArcField.setOutSeq(toIndexInt);
                    break;
                default:
                    break;
            }
            updateObj.add(toArcField);
            if (fromIndexInt < toIndexInt) {//下移
                for (int i = fromIndexInt + 1; i <= toIndexInt; i++) {
                    ArcField obj = new ArcField();
                    obj.setFieldId(list.get(i).getFieldId());
                    switch (bizType) {
                        case 1://著录排序（门类表所有字段都为默认著录字段  不做过滤）
                            obj.setInSeq(i - 1);
                            break;
                        case 2://档号排序 （过滤是档号的数据）
                            obj.setArcSeq(i - 1);
                            break;
                        case 3://浏览排序设置排序 （过滤是排序字段的数据）
                            obj.setOutOrderSeq(i - 1);
                            break;
                        case 4://4浏览界面排序 （过滤是浏览界面的数据）
                            obj.setOutSeq(i - 1);
                            break;
                        default:
                            break;
                    }
                    updateObj.add(obj);
                }

            } else {//上移
                for (int i = toIndexInt; i < fromIndexInt; i++) {
                    ArcField obj = new ArcField();
                    obj.setFieldId(list.get(i).getFieldId());
                    switch (bizType) {
                        case 1://著录排序（门类表所有字段都为默认著录字段  不做过滤）
                            obj.setInSeq(i + 1);
                            break;
                        case 2://档号排序 （过滤是档号的数据）
                            obj.setArcSeq(i + 1);
                            break;
                        case 3://浏览排序设置排序 （过滤是排序字段的数据）
                            obj.setOutOrderSeq(i + 1);
                            break;
                        case 4://4浏览界面排序 （过滤是浏览界面的数据）
                            obj.setOutSeq(i + 1);
                            break;
                        default:
                            break;
                    }
                    updateObj.add(obj);
                }
            }
            this.saveOrUpdateBatch(updateObj);
            return ResultBody.ok();
        }
        int sourceIndex = -1;
        int targetIndex = -1;
        for (int i = 0; i < list.size(); i++) {
            ArcField obj = list.get(i);
            if (obj.getFieldId().equals(fieldId)) {
                if (type == 1) {//上移
                    if (i == 0) {
                        return ResultBody.failed("无法上移");
                    } else {
                        sourceIndex = i;
                        targetIndex = i - 1;
                    }
                } else if (type == 2) {//下移
                    if (i == list.size() - 1) {
                        return ResultBody.failed("无法下移");
                    } else {
                        sourceIndex = i;
                        targetIndex = i + 1;
                    }
                }
            }
        }
        if (sourceIndex < 0 || targetIndex < 0) {
            return ResultBody.failed("移动错误");
        }
        Long targetId = list.get(sourceIndex).getFieldId();
        list.get(sourceIndex).setFieldId(list.get(targetIndex).getFieldId());
        list.get(targetIndex).setFieldId(targetId);
        List<ArcField> updateObj = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            ArcField obj = new ArcField();
            obj.setFieldId(list.get(i).getFieldId());
            switch (bizType) {
                case 1://著录排序（门类表所有字段都为默认著录字段  不做过滤）
                    obj.setInSeq(i);
                    break;
                case 2://档号排序 （过滤是档号的数据）
                    obj.setArcSeq(i);
                    break;
                case 3://浏览排序设置排序 （过滤是排序字段的数据）
                    obj.setOutOrderSeq(i);
                    break;
                case 4://4浏览界面排序 （过滤是浏览界面的数据）
                    obj.setOutSeq(i);
                    break;
                default:
                    break;
            }
            updateObj.add(obj);
        }
        this.saveOrUpdateBatch(updateObj);
        return ResultBody.ok();
    }

    @Override
    public List<ArcField> listByCategoryId(Long categoryId) {
        CriteriaQuery<ArcField> fieldQuery = new CriteriaQuery<ArcField>(ArcField.class);
        fieldQuery.lambda().eq(ArcField::getCategoryId, categoryId);
        return this.list(fieldQuery);
    }

    @Override
    public ArcField getArcField(Long categoryId) {
        QueryWrapper<ArcField> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ArcField::getCategoryId, categoryId)
                .eq(ArcField::getIsMount, ArchiveEnumInteger.IS_TRUE.getCode());
        List<ArcField> arcFields = list(queryWrapper);
        return arcFields.size() > 0 ? arcFields.get(0) : null;
    }

    @Override
    public void copyArcCategoryField(ArcCategory srcCategory, ArcCategory copyCategory) {
        ApiAssert.isNotEmpty("创建门类不能为空", srcCategory);
        ApiAssert.isNotEmpty("模板门类不能为空", copyCategory);
        //原始id与复制后id映射关机
        Map<Long, Long> idRef = new HashMap<>();


        //字段复制
        List<ArcField> copyArcFields = this.listByCategoryId(copyCategory.getCategoryId());
        if (FlymeUtils.isEmpty(copyArcFields)) {
            return;
        }
        List<ArcField> srcArcFields = new ArrayList<>();
        copyArcFields.forEach(item -> {
            ArcField arcField = new ArcField();
            BeanUtil.copyProperties(item, arcField);
            arcField.setFieldId(idRef.computeIfAbsent(item.getFieldId(), key -> {
                return IdWorker.getId();
            }));
            arcField.setCategoryId(srcCategory.getCategoryId());
            srcArcFields.add(arcField);
        });
        //this.saveBatch(srcArcFields);
        this.mutiInsert(srcArcFields);
        Map<Long, ArcField> fieldsMap = srcArcFields.stream().collect(Collectors.toMap(ArcField::getFieldId, ArcField -> ArcField));
        //二级分类
        List<ArcCategorySecond> copyCategorySeconds = this.arcCategorySecondService.list(Wrappers.lambdaQuery(ArcCategorySecond.class)
                .eq(ArcCategorySecond::getCategoryId, copyCategory.getCategoryId()));
        if (FlymeUtils.isNotEmpty(copyCategorySeconds)) {
            List<ArcCategorySecond> categorySeconds = new ArrayList<>();
            copyCategorySeconds.forEach(item -> {
                ArcCategorySecond categorySecond = new ArcCategorySecond();
                BeanUtil.copyProperties(item, categorySecond);
                categorySecond.setCategorySecondId(idRef.computeIfAbsent(categorySecond.getCategorySecondId(), key -> {
                    return IdWorker.getId();
                }));
                categorySecond.setCategoryId(srcCategory.getCategoryId());
                categorySecond.setParentId(idRef.computeIfAbsent(categorySecond.getParentId(), key -> {
                    return categorySecond.getParentId() == 0 ? 0L : IdWorker.getId();
                }));
                categorySeconds.add(categorySecond);
                List<ArcSecondField> copySecondFields = this.arcSecondFieldService.list(Wrappers.lambdaQuery(ArcSecondField.class)
                        .eq(ArcSecondField::getCategorySecondId, item.getCategorySecondId()));
                if (FlymeUtils.isNotEmpty(copySecondFields)) {
                    List<ArcSecondField> secondFields = new ArrayList<>();
                    copySecondFields.forEach(obj -> {
                        ArcSecondField secondField = new ArcSecondField();
                        BeanUtil.copyProperties(obj, secondField);
                        secondField.setSecondFieldId(IdWorker.getId());
                        secondField.setCategorySecondId(idRef.get(obj.getCategorySecondId()));
                        secondField.setFieldId(idRef.get(obj.getFieldId()));
                        secondField.setCategoryId(srcCategory.getCategoryId());

                        secondField.setColumnLength(fieldsMap.get(secondField.getFieldId()).getColumnLength());
                        secondField.setDataType(fieldsMap.get(secondField.getFieldId()).getDataType());
                        secondField.setDefaultValue(fieldsMap.get(secondField.getFieldId()).getDefaultValue());
                        secondField.setDictCode(fieldsMap.get(secondField.getFieldId()).getDictCode());
                        secondField.setFieldCnName(fieldsMap.get(secondField.getFieldId()).getFieldCnName());
                        secondField.setFieldName(fieldsMap.get(secondField.getFieldId()).getFieldName());
                        secondField.setInType(fieldsMap.get(secondField.getFieldId()).getInType());

                        secondFields.add(secondField);
                    });
                    if (FlymeUtils.isNotEmpty(secondFields)) {
                        //this.arcSecondFieldService.saveBatch(secondFields);
                        this.arcSecondFieldService.mutiInsert(secondFields);
                    }
                }


            });
            //this.arcCategorySecondService.saveBatch(categorySeconds);
            this.arcCategorySecondService.mutiInsert(categorySeconds);

        }
    }

    @Override
    public void delArcField(Long categoryId) {

        CriteriaQuery<ArcField> fdQuery = new CriteriaQuery<ArcField>(ArcField.class);
        fdQuery.lambda().eq(ArcField::getCategoryId, categoryId);
        this.baseMapper.delete(fdQuery);

    }

    public static void main(String[] args) {
        //    [qp3@]

        System.out.println("\\");
        String s = "aaaa333\\\\";
        //Pattern p = Pattern.compile("/[\\/:*?\"<>|]/g");
        Pattern p = Pattern.compile("/[\\/:*?\"<>|]/g");
        Matcher m = p.matcher(s);
        System.out.println(m.find() || s.contains("\\"));
    }
}
